#include "groupmodel.hpp"
#include "db/db.h"
#include "mysql_conn_pool.hpp"

//创建群组
bool GroupModel::createGroup(Group& group){
    //往数据表allgroup(groupname:群名称，groupdesc:群功能描述（备注）)添加一个信息
    //考虑到有备注，sql字符数组空间取大一点2048

    char sql[2048]={0};
    
    sprintf(sql,"insert into allgroup(groupname,groupdesc) values('%s','%s')",
        group.getName().c_str(),group.getDesc().c_str());
    
    //从数据库连接池中获取连接对象，并且使用RAII机制
    MySQL* mysql = nullptr;
    mysql_connpool_RAII RAII(&mysql,mysql_connPool::getInstance());

    if(mysql!=nullptr){
        if(mysql->update(sql)){
            //插入成功则获取刚刚的群组自增属性ID
            group.setID(mysql_insert_id(mysql->getConnection()));
            return true;
        }
    }
    return false;
}

/**
 * 用户加入群组
 * @param userid: 要加入的群组的用户ID
 * @param groupid: 要加入的群组ID
 * @param role: 用户userid在群组中的角色作用（管理者还是普通成员）
 */
bool GroupModel::addGroup(int userid,int groupid,string role){
    //往数据表groupuser(groupid,userid,grouprole["creator","normal"])添加数据

    char sql[256]={0};
    sprintf(sql,"insert into groupuser values('%d','%d','%s')",
        groupid,userid,role.c_str());
    
    //从数据库连接池中获取连接对象，并且使用RAII机制
    MySQL* mysql = nullptr;
    mysql_connpool_RAII RAII(&mysql,mysql_connPool::getInstance());

    if(mysql!=nullptr){
        if(mysql->update(sql)){
            //语句运行成功返回true
            return true;
        }
    }

    return false;
}

//获取用户所在群组的信息
vector<Group> GroupModel::queryGroups(int userid){
    /**
     * 1、先把groupuser表和allgroup连接
     * 2、在这个连接的表里面，查找userid所在的表，并过滤数据
     * 3、返回最后数据，并且push到数组中
     * 
     * 4、遍历Group数组，为每个Group对象里的成员列表添加数据
     * 5、return
     */

    char sql[1024]={0};
    sprintf(sql,"select a.id,a.groupname,a.groupdesc from allgroup a inner join \
        groupuser b on a.id=b.groupid where b.userid=%d",userid);

    //该方法返回的Group数组
    vector<Group> groupsArr;
    
    //从数据库连接池中获取连接对象，并且使用RAII机制
    MySQL* mysql = nullptr;
    mysql_connpool_RAII RAII(&mysql,mysql_connPool::getInstance());

    if(mysql!=nullptr){
        MYSQL_RES* res=mysql->query(sql);
        if(res!=nullptr){
            MYSQL_ROW row;
            while((row = mysql_fetch_row(res))!=nullptr){
                Group group;
                group.setID(atoi(row[0]));
                group.setName(row[1]);
                group.setDesc(row[2]);

                groupsArr.push_back(group);
            }
        }
        mysql_free_result(res);
        
    }
    

    //4、遍历Group数组，为每个Group对象里的成员列表添加数据
    for(Group& group:groupsArr){
        sprintf(sql,"select a.id,a.name,a.state,b.grouprole from `user` a inner join \
            groupuser b on a.id=b.userid where b.groupid = %d",group.getID());
        MYSQL_RES* res=mysql->query(sql);
        if(res!=nullptr){
            MYSQL_ROW row;
            while((row = mysql_fetch_row(res))!=nullptr){
                GroupUser user;
                user.setID(atoi(row[0]));
                user.setName(row[1]);
                user.setState(row[2]);
                user.setRole(row[3]);

                group.getUsers().push_back(user);                
            }
        }
        mysql_free_result(res);
    }

    return groupsArr;
}

//根据userid查询群组里用户id列表（除了自己之外）
//该方法主要用于给群里其它成员发送消息
vector<int> GroupModel::queryGroupUsers(int userid,int groupid){
    char sql[1024]={0};
    //注意是查找除了我（userid）的成员，有个and条件
    sprintf(sql,"select userid from groupuser where groupid = %d and userid != %d",groupid,userid);

    //返回一个数组，该数组包含该群组里面其他人的用户id
    vector<int> idArr;
    
    //从数据库连接池中获取连接对象，并且使用RAII机制
    MySQL* mysql = nullptr;
    mysql_connpool_RAII RAII(&mysql,mysql_connPool::getInstance());

    if(mysql!=nullptr){
        MYSQL_RES* res=mysql->query(sql);
        if(res!=nullptr){
            MYSQL_ROW row;
            while((row=mysql_fetch_row(res))!=nullptr){
                idArr.push_back(atoi(row[0]));
            }
        }
        mysql_free_result(res);
    }
    return idArr;
}